package com.currency.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.currency.bean.QueryCoinsTradeBean;
import com.currency.constant.MarkCode;
import com.currency.exception.AppException;
import com.currency.mapper.*;
import com.currency.pojo.*;
import com.currency.request.AddExtFeeRequest;
import com.currency.request.FreezeCoinsRequest;
import com.currency.request.PrePayRequest;
import com.currency.request.TransUserCoinsRequest;
import com.currency.response.BaseResponse;
import com.currency.response.NormalResponse;
import com.currency.response.QueryCoinsListResponse;
import com.currency.response.QueryTradeResponse;
import com.currency.service.PayService;
import com.currency.util.PayUtil;
import com.currency.util.XmlToJson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("payService")
@Slf4j
public class PayServiceImpl implements PayService {
    @Autowired
    private PayAccountMapper payAccountMapper;

    @Autowired
    private TradeSerialMapper tradeSerialMapper;

    @Autowired
    private PayDetailMapper payDetailMapper;

    @Autowired
    private WithdrawalDetailMapper withdrawalDetailMapper;

    @Autowired
    private CoinsFreezeMapper freezeMapper;

    @Autowired
    private CoinsTransMapper transMapper;

    @Autowired
    private NormalMapper normalMapper;

    @Autowired
    private WytPrePayOrderMapper prePayOrderMapper;

    @Autowired
    WytTaxServiceFeeMapper taxServiceFeeMapper;

    @Autowired
    WytCoinsTradeResumeMapper coinsTradeResumeMapper;

    @Autowired
    WytDataDictMapper wytDataDictMapper;

    @Autowired
    WytArrearsDetailMapper wytArrearsDetailMapper;

    @Autowired
    WytMonthlyClientArrearsMapper wytMonthlyClientArrearsMapper;

    @Autowired
    private WytAdvancePaymentMapper wytAdvancePaymentMapper;

    @Value("${sys.alipay.app_cert_path}")
    private String appCertPath;
    @Value("${sys.alipay.alipay_cert_path}")
    private String alipayCertPath;
    @Value("${sys.alipay.alipay_root_cert_path}")
    private String alipayRootCertPath;

    @Value("${sys.machineId}")
    private Integer machineId;
    @Value("${sys.futaiId}")
    private String futaiId;

    @Override
    public String wxPay(String payId, int amount) throws AppException {
        return PayUtil.postForWX(payId, amount);
    }

    @Override
    public String wxWithdrawal(String payId, String userId, Integer coins) throws AppException {
        freezeCoins(userId, coins);
        return "wxWithdrawalParams";
    }

    @Override
    public String apPay(String payId, int amount) throws Exception {
        AlipayTradeAppPayResponse payRes = PayUtil.postFroLipayNew(payId, amount, appCertPath, alipayCertPath, alipayRootCertPath);
        return payRes.getBody();
    }

    @Override
    public String apWithdrawal(String payId, String userId, Integer coins) throws AppException {
        freezeCoins(userId, coins);
        return "wxWithdrawalParams";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse freezeUserCoins(FreezeCoinsRequest request) throws Exception {
        WytCurrencyCoinsFreeze freeze = freezeMapper.selectOne(new QueryWrapper<WytCurrencyCoinsFreeze>().eq("freeze_order_id", request.getFreezeOrderId()).eq("freeze_type", request.getFreezeType()));
        if (freeze != null) {
            if (StringUtils.equalsIgnoreCase(request.getFreezeType() + "", "6")) {
                initFreeze(request, freeze);
                freezeMapper.updateById(freeze);
                return new BaseResponse("cey0000", "冻结金币成功");
            } else {
                throw new AppException("cey9988", "此运单已经冻结过了");
            }
        } else {
            freeze = new WytCurrencyCoinsFreeze();
            freeze.setFreezeId("Frz" + IdUtil.createSnowflake(machineId, 0).nextIdStr());
            initFreeze(request, freeze);
            freezeMapper.insert(freeze);
            return new BaseResponse("cey0000", "冻结金币成功");
        }
    }

    private void initFreeze(FreezeCoinsRequest request, WytCurrencyCoinsFreeze freeze) throws Exception {
        freeze.setFreezeOrderId(request.getFreezeOrderId());
        freeze.setFreezeStatus(MarkCode.FREEZE_TYPE_FREEZE);
        freeze.setFreezeReason(request.getFreezeReason());
        freeze.setFreezeType(request.getFreezeType());
        freeze.setUserId(request.getUserId());
        if (StringUtils.equalsIgnoreCase(request.getCoinsType(), MarkCode.COINS_TYPE_YUAN)) {
            freeze.setFreezeCoins(Integer.parseInt(PayUtil.yuanToFen(request.getFreezeCoins())));
        } else {
            freeze.setFreezeCoins(Integer.parseInt(request.getFreezeCoins()));
        }
        freezeCoins(freeze.getUserId(), freeze.getFreezeCoins());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse transUserCoins(TransUserCoinsRequest request) throws Exception {
        //查询冻结的订单
        QueryWrapper<WytCurrencyCoinsFreeze> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("freeze_order_id", request.getOrderId()).eq("freeze_status", MarkCode.FREEZE_TYPE_FREEZE).eq("freeze_type", request.getFreezeType());
        WytCurrencyCoinsFreeze freeze = freezeMapper.selectOne(queryWrapper);
        if (freeze == null || StringUtils.isBlank(freeze.getFreezeId())) {
            //throw new AppException("cey1010", "未找到订单对应的冻结订单");
            log.warn("未找到订单未找到订单对应的冻结订单");
            return new BaseResponse("cey0000", "兼容未冻结货主订单情况");
        }
        if (StringUtils.equalsIgnoreCase(MarkCode.UNFREEZE_BACK, request.getUnFreezeType())) {
            // 原路退回
            openCoins(freeze.getUserId(), freeze.getFreezeCoins());
            // 冻结订单解冻
            freeze.setFreezeReason(request.getUnFreezeReason());
            freeze.setFreezeStatus(MarkCode.FREEZE_TYPE_UNFREEZE);
            freezeMapper.updateById(freeze);
            return new BaseResponse("cey0000", "金币解冻成功");
        } else {
            String payUserId = freeze.getUserId();
            WytCurrencyPayAccountPojo transUser = payAccountMapper.selectById(payUserId);
            // 转移给其他人
            // 减去发货人的冻结的金币
            transUser.setUserFreezeCoins(transUser.getUserFreezeCoins() - freeze.getFreezeCoins());
            if (transUser.getUserFreezeCoins() < 0) {
                // 冻结金币小于0
                throw new AppException("cey9999", "余额不足，无法交易");
            }

            // 查询接收人
            WytCurrencyPayAccountPojo recUser = payAccountMapper.selectById(request.getRecUserId());
            // 司机增加金币
            recUser.setUserCoins(recUser.getUserCoins() + request.getAmount());
            //增加订单转移表
            WytCurrencyCoinsTrans trans = new WytCurrencyCoinsTrans();
            trans.setTransId("TC" + IdUtil.getSnowflake(machineId, 0).nextIdStr());

            trans.setFreezeId(freeze.getFreezeId());
            // 更新冻结订单状态
            freeze.setFreezeReason(request.getUnFreezeReason());
            freeze.setFreezeStatus(MarkCode.FREEZE_TYPE_UNFREEZE);
            freezeMapper.updateById(freeze);

            trans.setPayUserId(payUserId);
            trans.setRecUserId(recUser.getUserId());
            transMapper.insert(trans);
            // 金币更新
            payAccountMapper.updateById(transUser);
            payAccountMapper.updateById(recUser);

            return new BaseResponse("cey0000", "金币转移成功");
        }
    }

    @Override
    public QueryCoinsListResponse coinsList(String userId, String month, String coinsType) throws Exception {
        QueryWrapper<WytCurrencyTradeSerial> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).ge("create_datetime", month);
        List<WytCurrencyTradeSerial> dataList = tradeSerialMapper.selectList(queryWrapper);
        List<QueryCoinsTradeBean> data = new ArrayList<>();
        if (dataList != null && dataList.size() > 0) {
            for (WytCurrencyTradeSerial serial : dataList) {
                QueryCoinsTradeBean bean = new QueryCoinsTradeBean();
                bean.setTradeId(serial.getTradeId());
                bean.setCoinsType(coinsType);
                if (StringUtils.equalsIgnoreCase(coinsType, MarkCode.COINS_TYPE_YUAN)) {
                    bean.setTradeCoins(PayUtil.getYuanAmountForStr(serial.getTradeCoins()));
                } else {
                    bean.setTradeCoins(serial.getTradeCoins() + "");
                }
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                bean.setTradeDateTime(df.format(serial.getCreateDatetime()));
                bean.setTradeDesc(serial.getTradeRemark());
                bean.setTradeType(serial.getTradeType());
                bean.setTradeStatus(serial.getTradeStatus());
                data.add(bean);
            }
        }
        QueryCoinsListResponse response = new QueryCoinsListResponse();
        response.setErrCode("cey0000");
        response.setErrMsg("查询成功");
        response.setData(data);
        return response;
    }


    public void freezeCoins(String userId, Integer coins) throws AppException {
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(userId);

        if (accountPojo == null || !StringUtils.equalsIgnoreCase(userId, accountPojo.getUserId())) {
            // 查询不到用户账户信息
            throw new AppException("cey1010", "查询不到账户信息");
        }

        if (coins.compareTo(accountPojo.getUserCoins()) > 0) {
            // 提现余额不足
            throw new AppException("cey1011", "客户余额不足");
        }
        //冻结金额
        accountPojo.setUserCoins(accountPojo.getUserCoins() - coins);
        accountPojo.setUserFreezeCoins(accountPojo.getUserFreezeCoins() + coins);
        if (payAccountMapper.updateById(accountPojo) <= 0) {
            throw new AppException("cey1013", "金额冻结失败！");
        }
    }

    /**
     * 解冻
     *
     * @param userId
     * @param coins
     */
    public void openCoins(String userId, Integer coins) throws AppException {
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(userId);
        if (accountPojo == null || !StringUtils.equalsIgnoreCase(userId, accountPojo.getUserId())) {
            // 查询不到用户账户信息
            throw new AppException("cey1010", "查询不到账户信息");
        }
        //解冻金额
        accountPojo.setUserCoins(accountPojo.getUserCoins() + coins);
        accountPojo.setUserFreezeCoins(accountPojo.getUserFreezeCoins() - coins);
        if (payAccountMapper.updateById(accountPojo) <= 0) {
            throw new AppException("cey1013", "金额解冻失败！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse prePay(PrePayRequest request) throws AppException {
        // 查询是否已经申请过了。
        WytPrePayOrderPojo dataPojo = prePayOrderMapper.selectOne(new QueryWrapper<WytPrePayOrderPojo>().eq("order_id", request.getOrderId()));
        if (dataPojo != null) {
            throw new AppException("cey0012", "请勿重复发起结算申请");
        }

        // 新建申请预付款信息
        WytPrePayOrderPojo prePayOrderPojo = new WytPrePayOrderPojo();
        prePayOrderPojo.setOrderId(request.getOrderId());
        prePayOrderPojo.setDriverId(request.getDriverId());
        prePayOrderPojo.setWaybillId(request.getWaybillId());

        Map<String, Object> map = normalMapper.queryWayBillInfo(prePayOrderPojo.getWaybillId());
        if (map == null) {
            throw new AppException("cey9900", "货源订单号为空");
        }

        String shipmentId = map.get("shipment_id").toString();
        // 增加税后单价
        BigDecimal allFee = new BigDecimal(map.get("all_fee").toString());
        // 扣税
        WytTaxServiceFeePojo fee = taxServiceFeeMapper.selectById(1);
        if (fee == null || fee.getTaxRate() == 0) {
            fee = new WytTaxServiceFeePojo();
            fee.setTaxRate(9);
            fee.setServiceRate(5);
        }

        // 税费
        float feeF = fee.getTaxRate() * 0.01f;
        BigDecimal feeRate = new BigDecimal(feeF);
        BigDecimal feePrice = allFee.multiply(feeRate);
        prePayOrderPojo.setFeePrice(feePrice);

        //服务费
        float feeService = fee.getServiceRate() * 0.01f;
        BigDecimal serviceRate = new BigDecimal(feeService);
        BigDecimal servicePrice = allFee.multiply(serviceRate);
        prePayOrderPojo.setServicePrice(servicePrice);

        //最后转交给自己的费用
        prePayOrderPojo.setPayPrice(allFee);

        // 货主ID
        prePayOrderPojo.setShipmentId(Long.valueOf(shipmentId));


        BigDecimal zeroDecimal = new BigDecimal("0.00");
        String coalId = map.get("coal_type").toString();
        WytDataDictPojo dictPojo = wytDataDictMapper.selectById(coalId);
        //计算保险费用
        if (request.getIsInsure() == 1) {
            if (zeroDecimal.compareTo(request.getInsureAmount()) == 0) {
                // 保险率 万分之
                BigDecimal insFeeRate = new BigDecimal(dictPojo.getInsuranceFee() == null ? 4 : dictPojo.getInsuranceFee());
                BigDecimal insFee = allFee.multiply(insFeeRate).divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP);
                prePayOrderPojo.setInsurancePrice(insFee);
            } else {
                prePayOrderPojo.setInsurancePrice(request.getInsureAmount());
            }
        } else {
            prePayOrderPojo.setInsurancePrice(zeroDecimal);
        }


        //计算司机应收总价
        BigDecimal transportPrice = new BigDecimal(map.get("transport_price").toString());
        BigDecimal unit;
        if (StringUtils.equalsIgnoreCase(dictPojo.getOtherValue(), "CAL_BY_WEIGHT")) {
            unit = new BigDecimal(map.get("weight").toString());
        } else {
            unit = new BigDecimal(map.get("volume").toString());
        }
        BigDecimal driverSumPrice = transportPrice.multiply(unit);
        prePayOrderPojo.setDriverSumPrice(driverSumPrice);
        prePayOrderPojo.setDriverGetPrice(driverSumPrice.subtract(prePayOrderPojo.getInsurancePrice()));


        // 计算平台收益 = 总价 - 税费 - 司机获取的钱
        BigDecimal platformProfits = allFee.subtract(prePayOrderPojo.getFeePrice()).subtract(prePayOrderPojo.getDriverSumPrice());
        prePayOrderPojo.setPlatformProfits(platformProfits);

        prePayOrderMapper.insert(prePayOrderPojo);
        // 修改运单状态
        if (normalMapper.updateOrderStatusToWaitPay(prePayOrderPojo.getOrderId()) <= 0) {
            throw new AppException("cey9999", "更新运单状态失败");
        }


        return new BaseResponse("cey0000", "申请预付款成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public NormalResponse addExtFee(AddExtFeeRequest request) throws AppException {
        //附加费用增加方法
        WytPrePayOrderPojo prePayOrderPojo = prePayOrderMapper.selectById(request.getPrePayId());
        if (prePayOrderPojo == null) {
            throw new AppException("cey8999", "未找到预付款ID");
        }

        // 先判断附件费用是否超过限额
        BigDecimal sumFee = prePayOrderPojo.getFeePrice().add(prePayOrderPojo.getPayPrice());
        sumFee = sumFee.add(prePayOrderPojo.getServicePrice());
        WytTaxServiceFeePojo fee = taxServiceFeeMapper.selectById(1);
        if (fee == null || fee.getExtMaxRate() == 0) {
            fee = new WytTaxServiceFeePojo();
            fee.setTaxRate(9);
            fee.setServiceRate(5);
            fee.setExtMaxRate(20);
        }
        float extMaxRate = fee.getExtMaxRate() * 0.01f;
        BigDecimal rate = new BigDecimal(extMaxRate);
        BigDecimal maxFee = sumFee.multiply(rate);

        if (maxFee.compareTo(request.getSubsidy()) < 0) {
            throw new AppException("cey9995", "补贴金额大于运费的" + fee.getExtMaxRate() + "%，操作被禁止");
        }

        if (maxFee.compareTo(request.getSurcharge()) < 0) {
            throw new AppException("cey9995", "附加费用金额大于运费的" + fee.getExtMaxRate() + "%，操作被禁止");
        }

        // 修改 审核费，装车费，卸车费，提现到油卡的比例
        prePayOrderPojo.setLoadingPrice(request.getLoadingPrice());
        prePayOrderPojo.setUnloadingPrice(request.getUnloadingPrice());
        prePayOrderPojo.setAuditPrice(request.getAuditPrice());
        prePayOrderPojo.setOilCardPercent(request.getOilCardPercent());

        // 修改司机实际所得
        BigDecimal driverGetPrice = prePayOrderPojo.getDriverGetPrice();
        prePayOrderPojo.setDriverGetPrice(driverGetPrice.subtract(prePayOrderPojo.getLoadingPrice()).subtract(prePayOrderPojo.getUnloadingPrice()).subtract(prePayOrderPojo.getAuditPrice()));

        // 更新预付款金额表
        prePayOrderPojo.setSubsidy(request.getSubsidy());
        prePayOrderPojo.setSubsidyMsg(request.getSubsidyMsg());
        prePayOrderPojo.setDriverGetPrice(prePayOrderPojo.getDriverGetPrice().add(request.getSubsidy()));

        prePayOrderPojo.setSurcharge(request.getSurcharge());
        prePayOrderPojo.setSurchargeMsg(request.getSurchargeMsg());

        // 更新收益
        BigDecimal platformProfits = prePayOrderPojo.getPayPrice().subtract(prePayOrderPojo.getFeePrice()).subtract(prePayOrderPojo.getDriverSumPrice());
        prePayOrderPojo.setPlatformProfits(platformProfits);

        prePayOrderMapper.updateById(prePayOrderPojo);

        NormalResponse response = new NormalResponse();
        response.setData(prePayOrderPojo);
        response.setErrCode("cey0000");
        response.setErrMsg("其他费用修改成功");

        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse ensurePrePay(String id) throws Exception {
        WytPrePayOrderPojo prePayOrderPojo = prePayOrderMapper.selectById(id);
        if (prePayOrderPojo == null) {
            throw new AppException("cey8999", "未找到预付款ID");
        }

        // 司机押金解冻
        TransUserCoinsRequest userCoinsRequest = new TransUserCoinsRequest();
        //queryWrapper.eq("freeze_order_id", request.getOrderId()).eq("freeze_status", MarkCode.FREEZE_TYPE_FREEZE).eq("freeze_type", request.getFreezeType());
        userCoinsRequest.setFreezeType(WytCurrencyCoinsFreeze.FREEZE_TYPE_DRIVER_DEPOSIT);
        userCoinsRequest.setOrderId(prePayOrderPojo.getOrderId());
        userCoinsRequest.setUnFreezeReason("运输完成解冻");
        userCoinsRequest.setUnFreezeType(WytCurrencyCoinsFreeze.UNFREEZE_REASON_BACK);
        userCoinsRequest.setRecUserId(prePayOrderPojo.getDriverId());
        userCoinsRequest.setUserId(prePayOrderPojo.getShipmentId() + "");
        userCoinsRequest.setAmount((prePayOrderPojo.getDriverGetPrice().multiply(new BigDecimal("100"))).intValue());
        transUserCoins(userCoinsRequest);


        // 货主冻结款转给司机
        BigDecimal payPrice = prePayOrderPojo.getPayPrice();
        BigDecimal rate = new BigDecimal(100);

        // 司机账户信息
        WytCurrencyPayAccountPojo driverAccount = payAccountMapper.selectById(prePayOrderPojo.getDriverId());
        // 福泰账户信息
        WytCurrencyPayAccountPojo futaiAccount = payAccountMapper.selectById(futaiId);

        // 货主账户信息
        WytCurrencyPayAccountPojo shipmentAccount = payAccountMapper.selectById(prePayOrderPojo.getShipmentId());

        // 转移的账户金额
        Integer payPriceInt = (payPrice.multiply(rate)).intValue();

        // 司机实际得到的钱
        Integer driverGetPrice = (prePayOrderPojo.getDriverGetPrice().multiply(rate)).intValue();

        // TODO 如果是月结用户，则直接增加欠款，不处理冻结的金币
        //减少货主冻结的付款金额
        Map<String, Object> shipmentMap = normalMapper.queryShipmentInfo(Long.parseLong(shipmentAccount.getUserId()));
        String isMonthlyClient = shipmentMap.get("is_monthly_client") == null ? "" : shipmentMap.get("is_monthly_client").toString();
        boolean monthlyFlag = StringUtils.equalsIgnoreCase(isMonthlyClient, "2");
        WytMonthlyClientArrearsPojo arrearsPojo = null;
        String dateYearMonthStr = DateUtils.formatDate(new Date(), "yyyy-MM");
        log.info("用户当前获取的年月为：" + dateYearMonthStr);
        if (monthlyFlag) {
            // 总账欠款增加
            arrearsPojo = wytMonthlyClientArrearsMapper.selectOne(
                    new QueryWrapper<WytMonthlyClientArrearsPojo>().eq("user_id", shipmentAccount.getUserId()).eq("arrears_year_month", dateYearMonthStr));
            if (arrearsPojo == null) {
                arrearsPojo = new WytMonthlyClientArrearsPojo();
                arrearsPojo.setAmount(0);
                arrearsPojo.setArrearsYearMonth(dateYearMonthStr);
                arrearsPojo.setId("arrs" + IdUtil.createSnowflake(1, 2).nextIdStr());
                arrearsPojo.setUserId(shipmentAccount.getUserId());
                wytMonthlyClientArrearsMapper.insert(arrearsPojo);
            } else {
                arrearsPojo.setAmount(arrearsPojo.getAmount() + payPriceInt);
                wytMonthlyClientArrearsMapper.updateById(arrearsPojo);
            }

            // 欠款明细增加
            WytArrearsDetailPojo detailPojo = new WytArrearsDetailPojo();
            detailPojo.setAmount(payPriceInt);
            detailPojo.setArrearsType(WytArrearsDetailPojo.ARREARS_TYPE_D);
            detailPojo.setArrearsYearMonth(dateYearMonthStr);
            detailPojo.setId("detail" + IdUtil.createSnowflake(2, 2).nextIdStr());
            detailPojo.setUserId(shipmentAccount.getUserId());
            detailPojo.setMessage("运单结算金币");
            detailPojo.setOrderId(prePayOrderPojo.getOrderId());
            wytArrearsDetailMapper.insert(detailPojo);
        } else {
            shipmentAccount.setUserFreezeCoins(shipmentAccount.getUserFreezeCoins() - payPriceInt);
        }
        //增加司机金额 ，并且部分修改到油卡里面
        int oilPrice = (int) (driverGetPrice * prePayOrderPojo.getOilCardPercent().floatValue());
        // 需要查询是否进行过提前付款
        WytAdvancePayment payment = wytAdvancePaymentMapper.selectOne(new QueryWrapper<WytAdvancePayment>().eq("order_id", prePayOrderPojo.getOrderId()));
        if (payment != null) {
            if (StringUtils.equalsIgnoreCase(payment.getStatus(), WytAdvancePayment.STATUS_SUCCESS)) {
                // 已经进行过提前付款
                oilPrice = oilPrice - payment.getAmount();
            } else {
                // 提前付款未审核，直接改为取消
                payment.setStatus(WytAdvancePayment.STATUS_FAILED);
                wytAdvancePaymentMapper.updateById(payment);
            }
        }
        driverAccount.setOilCoins(driverAccount.getOilCoins() + oilPrice);
        driverAccount.setUserCoins(driverAccount.getUserCoins() + driverGetPrice - oilPrice);

        //其他费用给福泰账户
        if (!monthlyFlag) {
            BigDecimal expPrice = prePayOrderPojo.getPayPrice().subtract(prePayOrderPojo.getDriverGetPrice());
            Integer expPriceInt = (expPrice.multiply(rate)).intValue();

            expPriceInt = shipmentAccount.getUserFreezeCoins() > expPriceInt ? expPriceInt : shipmentAccount.getUserFreezeCoins();

            //减少货主冻结的税费 服务费金额，增加福泰金额
            futaiAccount.setUserCoins(futaiAccount.getUserCoins() + expPriceInt);

            // 修改货主的金币冻结状态
            WytCurrencyCoinsFreeze freeze = freezeMapper.selectOne(new QueryWrapper<WytCurrencyCoinsFreeze>().eq("freeze_order_id", prePayOrderPojo.getWaybillId()).eq("freeze_status", MarkCode.FREEZE_TYPE_FREEZE).eq("user_id", prePayOrderPojo.getShipmentId()));
            if (freeze != null && !StringUtils.isBlank(freeze.getFreezeId())) {
                freeze.setFreezeStatus(WytCurrencyCoinsFreeze.FREEZE_STATUS_THAW);
                freezeMapper.updateById(freeze);
            }
        }

        BigDecimal hundred = new BigDecimal("100");
        BigDecimal sumPay = new BigDecimal(payPriceInt);
        //货主增加扣钱数据
        insertResume(sumPay.divide(hundred, 2, BigDecimal.ROUND_HALF_UP), WytCoinsTradeResumePojo.MUL, prePayOrderPojo.getShipmentId() + "",
                prePayOrderPojo.getWaybillId() + "", "货运完成，扣除金币");


        BigDecimal driverGetCnt = new BigDecimal(driverGetPrice);
        // 司机增加进钱数据
        insertResume(driverGetCnt.divide(hundred, 2, BigDecimal.ROUND_HALF_UP), WytCoinsTradeResumePojo.ADD, prePayOrderPojo.getDriverId() + "",
                prePayOrderPojo.getOrderId() + "", "运单完成，增加金币");

        BigDecimal zeroDecimal = new BigDecimal("0.00");


        //如果有附加费，额外扣除货主金币，福泰账户增加金币
        if (prePayOrderPojo.getSurcharge().compareTo(zeroDecimal) > 0) {
            int surcharge = (prePayOrderPojo.getSurcharge().multiply(hundred)).intValue();
            if (monthlyFlag) {
                arrearsPojo.setAmount(arrearsPojo.getAmount() + surcharge);
                wytMonthlyClientArrearsMapper.updateById(arrearsPojo);
                // 欠款明细增加
                WytArrearsDetailPojo detailPojo = new WytArrearsDetailPojo();
                detailPojo.setAmount(surcharge);
                detailPojo.setArrearsType(WytArrearsDetailPojo.ARREARS_TYPE_D);
                detailPojo.setArrearsYearMonth(dateYearMonthStr);
                detailPojo.setId("detail" + IdUtil.createSnowflake(2, 2).nextIdStr());
                detailPojo.setUserId(shipmentAccount.getUserId());
                detailPojo.setMessage("运单附加费用");
                detailPojo.setOrderId(prePayOrderPojo.getOrderId());
                wytArrearsDetailMapper.insert(detailPojo);
            } else {
                shipmentAccount.setUserCoins(shipmentAccount.getUserCoins() - surcharge);
            }
            futaiAccount.setUserCoins(futaiAccount.getUserCoins() + surcharge);
            insertResume(prePayOrderPojo.getSurcharge(), WytCoinsTradeResumePojo.MUL, prePayOrderPojo.getShipmentId() + "",
                    prePayOrderPojo.getWaybillId() + "", "货源运输附加费");
        }

        //如果有补贴费，额外增加司机金币，福泰账户减少金币
        if (prePayOrderPojo.getSubsidy().compareTo(zeroDecimal) > 0) {
            int subsidy = (prePayOrderPojo.getSubsidy().multiply(hundred)).intValue();
            futaiAccount.setUserCoins(futaiAccount.getUserCoins() - subsidy);
            insertResume(prePayOrderPojo.getSubsidy(), WytCoinsTradeResumePojo.ADD, prePayOrderPojo.getDriverId() + "",
                    prePayOrderPojo.getOrderId() + "", "运输补贴费用");
        }

        // 更新货主，福泰，司机金额
        if (!monthlyFlag) {
            payAccountMapper.updateById(shipmentAccount);
        }
        payAccountMapper.updateById(futaiAccount);
        payAccountMapper.updateById(driverAccount);
        // 更新预付款金额状态
        prePayOrderPojo.setStatus(2);
        prePayOrderMapper.updateById(prePayOrderPojo);
        // 更新运单状态到 5
        if (normalMapper.updateOrderStatusToFinished(prePayOrderPojo.getOrderId()) <= 0) {
            throw new AppException("cey9999", "更新运单状态失败");
        }

        return new BaseResponse("cey0000", "预付款审核通过，已经付款");
    }


    private void insertResume(BigDecimal amount, int type, String userId, String outId, String msg) {
        WytCoinsTradeResumePojo pojo = new WytCoinsTradeResumePojo();
        pojo.setAmount(amount);
        pojo.setType(type);
        pojo.setUserId(userId);
        pojo.setOutId(outId);
        pojo.setMsg(msg);
        coinsTradeResumeMapper.insert(pojo);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public QueryTradeResponse queryTrade(String tradeId, Integer flag) throws Exception {
        WytCurrencyTradeSerial tradeSerial = tradeSerialMapper.selectById(tradeId);

        if (tradeSerial == null || !StringUtils.equalsIgnoreCase(tradeId, tradeSerial.getTradeId())) {
            throw new AppException("cey1015", "订单不存在");
        }
        QueryTradeResponse response = new QueryTradeResponse();
        response.setErrCode("cey0000");
        response.setErrMsg("查询成功");

        if (MarkCode.TRADE_STATUS_SUCCESS.equals(tradeSerial.getTradeStatus())) {
            //是最终状态
            response.setTradeStatus(tradeSerial.getTradeStatus());
            return response;
        }

        String outId = tradeSerial.getAssociatedId();
        WytCurrencyPayDetailPojo payDetailPojo = payDetailMapper.selectById(tradeSerial.getAssociatedId());

        BigDecimal hundred = new BigDecimal(100);
        BigDecimal tradeAmount = new BigDecimal(tradeSerial.getTradeCoins()).divide(hundred, 2, BigDecimal.ROUND_HALF_UP);
        if (StringUtils.isBlank(payDetailPojo.getReturnParams())) {
            throw new AppException("cey9999", "订单状态异常，请取消");
        } else if (payDetailPojo.getReturnParams().startsWith("alipay")) {
            //支付宝查询第三方结果
            AlipayTradeQueryResponse queryResponse = PayUtil.postForAliPayOrderInfo(tradeSerial.getAssociatedId(), appCertPath, alipayCertPath, alipayRootCertPath);
            if (StringUtils.equalsIgnoreCase(queryResponse.getTradeStatus(), "TRADE_SUCCESS")) {
                //交易成功
                successTrade(tradeSerial);
                response.setTradeStatus(MarkCode.TRADE_STATUS_SUCCESS);
                insertResume(tradeAmount, WytCoinsTradeResumePojo.ADD_RECHARGE, tradeSerial.getUserId(), tradeSerial.getTradeId(), "充值增加金币");
            } else {
                cancelTrade(tradeSerial);
                response.setTradeStatus(MarkCode.TRADE_STATUS_CANCEL);
            }
        } else {
            //微信查询第三方结果
            String wechatQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
            UUID uuid = UUID.randomUUID();
            String nonce_str = uuid.toString().replace("-", "");
            StringBuffer allParam = new StringBuffer();
            allParam.append("appid=" + PayUtil.appid + "&");
            allParam.append("mch_id=" + PayUtil.mch_id + "&");
            allParam.append("nonce_str=").append(nonce_str).append("&");
            allParam.append("out_trade_no=").append(outId).append("&");

            String sign = DigestUtils.md5Hex(allParam.toString() + "key=b534811e05584cff8593237757dad7a2");
            System.out.println(sign);

            StringBuffer stringBuffer = new StringBuffer("");
            stringBuffer.append("<xml>");
            stringBuffer.append("<appid>" + PayUtil.appid + "</appid>");
            stringBuffer.append("<mch_id>" + PayUtil.mch_id + "</mch_id>");
            stringBuffer.append("<nonce_str>").append(nonce_str).append("</nonce_str>");
            stringBuffer.append("<out_trade_no>").append(outId).append("</out_trade_no>");
            stringBuffer.append("<sign>").append(sign.toUpperCase()).append("</sign>");
            stringBuffer.append("</xml>");

            log.info(stringBuffer.toString());
            String ans = HttpUtil.post(wechatQueryUrl, stringBuffer.toString());

            log.info(ans);
            JSONObject json;
            try {
                json = XmlToJson.xml2Json(ans);
                System.out.println(json.toJSONString());
            } catch (Exception e) {
                System.out.println("转换xml时，出现异常");
                e.printStackTrace();
                throw new AppException("cy9992", "微信支付网络出现异常");
            }
            if (StringUtils.equalsIgnoreCase(json.getString("trade_state"), "SUCCESS")) {
                successTrade(tradeSerial);
                response.setTradeStatus(MarkCode.TRADE_STATUS_SUCCESS);
                insertResume(tradeAmount, WytCoinsTradeResumePojo.ADD_RECHARGE, tradeSerial.getUserId(), tradeSerial.getTradeId(), "充值增加金币");
            } else {
                cancelTrade(tradeSerial);
                response.setTradeStatus(MarkCode.TRADE_STATUS_CANCEL);
            }
        }

        return response;
    }

    public void cancelTrade(WytCurrencyTradeSerial tradeSerial) throws AppException {
        //远程取消订单
        if (!MarkCode.TRADE_STATUS_CANCEL.equals(tradeSerial.getTradeStatus())) {
            tradeSerial.setTradeStatus(MarkCode.TRADE_STATUS_CANCEL);
            if (tradeSerial.getTradeType().compareTo(MarkCode.TRADE_TYPE_PAY) > 0) {
                // 提现的话冻结金额回滚
                openCoins(tradeSerial.getUserId(), tradeSerial.getTradeCoins());
            }
            tradeSerialMapper.updateById(tradeSerial);
        }
    }

    private void successTrade(WytCurrencyTradeSerial tradeSerial) {
        tradeSerial.setTradeStatus(MarkCode.TRADE_STATUS_SUCCESS);
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(tradeSerial.getUserId());
        if (tradeSerial.getTradeType().intValue() == MarkCode.TRADE_TYPE_WITHDRAWAL) {
            // 提现的冻结金额减少
            accountPojo.setUserFreezeCoins(accountPojo.getUserFreezeCoins() - tradeSerial.getTradeCoins());
        } else {
            // 充值增加当前金额
            accountPojo.setUserCoins(accountPojo.getUserCoins() + tradeSerial.getTradeCoins());
        }
        payAccountMapper.updateById(accountPojo);
        tradeSerialMapper.updateById(tradeSerial);
    }

}
